﻿using System.Windows;
using System.Windows.Media.Animation;

namespace Red.Controls.Utils
{
    /// <summary>
    /// Used to allow classes to intercept animation requests
    /// </summary>
    /// <remarks>
    /// This interface exists because WPF IAnimatable doesn't allow me access to the details of the animation once it's begun
    /// </remarks>
    public interface IAnimationWrapper
    {
        /// <summary>
        /// Wraps <see cref="IAnimatable.BeginAnimation"/>
        /// </summary>
        void BeginAnimation( DependencyProperty dp, AnimationTimeline anim );

        /// <summary>
        /// Get the "To" value if a property is being animated, or else it's current value if not
        /// </summary>
        /// <remarks>
        /// Implementation will need to store the "To" values of animatable properties
        /// </remarks>
        object GetActualValue( DependencyProperty dp );

        /// <summary>
        /// Set a value directly without animation
        /// </summary>
        /// <remarks>
        /// This ensures that whatever mechanism remembers the "To" value of an animation is also updated
        /// </remarks>
        void SetValueDirect( DependencyProperty dp, object value );
    }

    public static class AnimationWrapperExtension
    {
        /// <summary>
        /// This function will attempt to extract the destination "To" value of an animation
        /// </summary>
        /// <remarks>
        /// WPF provides no way to access the value from the base class, and the property being animated gives you the current value as set by the animation.
        /// 
        /// Currently supports KeyFrame animations and DoubleAnimation (all other animation types return <see langword="null"/>)
        /// Implement as required
        /// </remarks>
        public static object ExtractTargetValue( this IAnimationWrapper wrapper, AnimationTimeline anim )
        {
            IKeyFrameAnimation kfAnim = anim as IKeyFrameAnimation;

            if ( kfAnim != null )
            {
                return ( (IKeyFrame)kfAnim.KeyFrames[ kfAnim.KeyFrames.Count - 1 ] ).Value;
            }

            DoubleAnimation dAnim = anim as DoubleAnimation;

            if ( dAnim != null )
            {
                return dAnim.To;
            }

            return null;
        }
    }
}
